'use client';

import { useState } from 'react';
import type { IMenu, IRole } from '@/interfaces';
import { useMutation, useQuery } from '@tanstack/react-query';
import {
  assignMenu,
  queryAllMenuAndSubmenu,
  queryRoleMenusById,
  unAssignMenu,
} from '@/services/api';
import useToast from '@/hooks/useToast';
import Alert from '@/app/[locale]/alert/alert';
import AlertLoad from '@/app/[locale]/alert/load';
import Box from '@/app/[locale]/admin/common/box';
import Nodata from '@/app/[locale]/common/nodata/nodata';
import Spinner from '@/app/[locale]/component/spinner/spinner';
import type { PrefixedTTranslatedFields } from '@/lib/dictionaries';

export default function MenuRoleAdminPage(
  this: any,
  {
    source,
    translatedFields,
  }: {
    source: IRole;
    translatedFields: PrefixedTTranslatedFields<'roleAdminPage'>;
  },
) {
  return (
    <Box>
      <div className="row">
        <div className="col">
          <RoleMenuList source={source} translatedFields={translatedFields} />
        </div>
        <div className="col">
          <MenuAddList source={source} translatedFields={translatedFields} />
        </div>
      </div>
    </Box>
  );
}

const RoleMenuList = ({
  source,
  translatedFields,
}: {
  source: IRole;
  translatedFields: PrefixedTTranslatedFields<'roleAdminPage'>;
}) => {
  const { show } = useToast();
  const [currentItem, setCurrentItem] = useState<IMenu>();

  const queryRoleMenusByIdQuery = useQuery(
    ['/roles', source.id, '/menus'],
    async (context) => {
      return (await queryRoleMenusById({
        id: context.queryKey[1] + '',
      })) as IMenu[];
    },
  );

  const unAssignMenuMutation = useMutation(unAssignMenu);

  async function onClickRemove(item: IMenu) {
    try {
      setCurrentItem(item);

      const id = item.id;
      const roleId = source.id + '';
      await unAssignMenuMutation.mutateAsync({
        id,
        data: {
          roleId,
        },
      });

      show({
        type: 'SUCCESS',
        message: translatedFields.operate.deleteCompleted,
      });
    } catch (e) {
      unAssignMenuMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    } finally {
      setCurrentItem(undefined);
    }
  }

  if (queryRoleMenusByIdQuery.data) {
    const data = queryRoleMenusByIdQuery.data;

    return (
      <div className="card">
        <div className="card-header bg-transparent text-secondary">
          <i className="bi bi-list me-2"></i>
          {translatedFields.properties.menuList}
        </div>
        <div className="card-body vstack gap-4">
          <div className="table-responsive">
            <table className="table align-middle">
              <thead>
                <tr className="text-nowrap">
                  <th scope="col" className="fw-normal">
                    ID
                  </th>
                  <th scope="col" className="fw-normal">
                    {translatedFields.properties.name}
                  </th>
                  <th scope="col" className="fw-normal">
                    {translatedFields.properties.path}
                  </th>
                  <th scope="col" className="fw-normal">
                    {translatedFields.properties.mainMenu}
                  </th>
                  <th scope="col" className=""></th>
                </tr>
              </thead>
              <tbody>
                {data.map((item) => {
                  return (
                    <tr key={item.id} className="text-nowrap">
                      <td>{item.id}</td>
                      <td>{item.name}</td>
                      <td>{item.path}</td>
                      <td>{item.type === 1 ? 'true' : 'false'}</td>
                      <td>
                        <button
                          disabled={
                            item.id === currentItem?.id &&
                            unAssignMenuMutation.isLoading
                          }
                          onClick={onClickRemove.bind(this, item)}
                          className="btn btn-sm btn-danger"
                          type="button"
                        >
                          {item.id === currentItem?.id &&
                          unAssignMenuMutation.isLoading ? (
                            <Spinner classs="me-2" />
                          ) : (
                            <i className="bi bi-trash me-2"></i>
                          )}
                          {translatedFields.operate.delete}
                        </button>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>

          {data.length === 0 && <Nodata />}
        </div>
      </div>
    );
  }

  if (queryRoleMenusByIdQuery.error) {
    return <Alert message={queryRoleMenusByIdQuery.error} type="error" />;
  }

  return <AlertLoad />;
};

const MenuAddList = ({
  source,
  translatedFields,
}: {
  source: IRole;
  translatedFields: PrefixedTTranslatedFields<'roleAdminPage'>;
}) => {
  const { show } = useToast();
  const [currentItem, setCurrentItem] = useState<IMenu>();

  const queryAllMenuAndSubmenuQuery = useQuery(
    ['/menus', '/submenus'],
    async () => {
      return (await queryAllMenuAndSubmenu()) as IMenu[];
    },
    {
      keepPreviousData: true,
    },
  );

  const assignMenuMutation = useMutation(assignMenu);

  async function onClickAdd(item: IMenu) {
    try {
      setCurrentItem(item);

      const id = item.id;
      const roleId = source.id + '';
      await assignMenuMutation.mutateAsync({
        id,
        data: {
          roleId,
        },
      });

      show({
        type: 'SUCCESS',
        message: translatedFields.operate.addCompleted,
      });
    } catch (e) {
      assignMenuMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    } finally {
      setCurrentItem(undefined);
    }
  }

  if (queryAllMenuAndSubmenuQuery.data) {
    const data = queryAllMenuAndSubmenuQuery.data;

    return (
      <div className="card">
        <div className="card-header bg-transparent text-secondary">
          <i className="bi bi-list me-2"></i>
          {translatedFields.properties.addMenu}
        </div>
        <div className="card-body vstack gap-4">
          <div className="table-responsive">
            <table className="table table-hover align-middle">
              <thead>
                <tr className="text-nowrap">
                  <th scope="col" className="">
                    ID
                  </th>
                  <th scope="col" className="">
                    {translatedFields.properties.name}
                  </th>
                  <th scope="col" className="">
                    {translatedFields.properties.path}
                  </th>
                  <th scope="col" className="">
                    {translatedFields.properties.mainMenu}
                  </th>
                  <th scope="col" className=""></th>
                </tr>
              </thead>
              <tbody>
                {data.map((item) => {
                  return (
                    <tr key={item.id} className="text-nowrap">
                      <td>{item.id}</td>
                      <td>{item.name}</td>
                      <td>{item.path}</td>
                      <td>{item.type === 1 ? 'true' : 'false'}</td>
                      <td>
                        <button
                          disabled={
                            item.id === currentItem?.id &&
                            assignMenuMutation.isLoading
                          }
                          onClick={onClickAdd.bind(this, item)}
                          className="btn btn-sm btn-light"
                          type="button"
                        >
                          {item.id === currentItem?.id &&
                          assignMenuMutation.isLoading ? (
                            <Spinner classs="me-2" />
                          ) : (
                            <i className="bi bi-plus-lg me-2"></i>
                          )}
                          添加
                        </button>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>

          {data.length === 0 && <Nodata />}
        </div>
      </div>
    );
  }

  if (queryAllMenuAndSubmenuQuery.error) {
    return <Alert message={queryAllMenuAndSubmenuQuery.error} type="error" />;
  }

  return <AlertLoad />;
};
